package com.springboot.cloud.demos.feign.rest;

import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.lly835.bestpay.config.WxPayConfig;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.service.BestPayService;
import com.lly835.bestpay.utils.JsonUtil;
import com.springboot.cloud.common.core.entity.vo.Result;
import com.springboot.cloud.common.core.exception.SystemErrorType;
import com.springboot.cloud.common.core.exception.UserErrorType;
import com.springboot.cloud.common.core.pay.AliAppPayService;
import com.springboot.cloud.common.core.pay.WeiXinPayService;
import com.springboot.cloud.common.core.util.DateUtils;
import com.springboot.cloud.demos.entity.enums.*;
import com.springboot.cloud.demos.entity.form.OrderForm;
import com.springboot.cloud.demos.entity.form.ProfitRecordForm;
import com.springboot.cloud.demos.entity.form.WalletForm;
import com.springboot.cloud.demos.entity.param.OrderQueryParam;
import com.springboot.cloud.demos.entity.po.MemberCard;
import com.springboot.cloud.demos.entity.po.Order;
import com.springboot.cloud.demos.entity.po.User;
import com.springboot.cloud.demos.entity.po.Wallet;
import com.springboot.cloud.demos.feign.service.*;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

//import com.springboot.cloud.common.core.pay.WeiXinPayService;

@RestController
@Log4j2
public class OrderController extends BaseController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private UserService userService;
    @Autowired
    private MemberCardService memberCardService;
    @Autowired
    private AliAppPayService aliAppPayService;
    @Autowired
    private BestPayService bestPayService;
    @Autowired
    private WeiXinPayService weiXinPayService;
    @Autowired
    private WalletService walletService;
    @Autowired
    private ProfitRecordService profitRecordService;
    @Autowired
    private WxPayConfig wxPayConfig;

    @RequestMapping(value = "/order", method = RequestMethod.POST)
    public Result save(HttpServletRequest servletRequest, @RequestBody OrderForm orderForm) {
        User user = getUser(servletRequest);
        orderForm.setUserId(user.getId());

        log.info("orderForm:{}", orderForm);
        Result<Order> result = orderService.add(orderForm);

        if (result.isSuccess()) {
            Order order = result.getData();
            BigDecimal payMoney = order.getPayMoney();
            String orderId = order.getId();

            if (MemberCardType.gold.getCode().equalsIgnoreCase(orderForm.getPayType())) {
                return payByGold(user, orderId, order.getMemberCardId());
            }
            //支付请求参数
            PayRequest request = new PayRequest();
            BestPayTypeEnum bestPayTypeEnum = BestPayTypeEnum.getByName(orderForm.getPayType());
            request.setPayTypeEnum(bestPayTypeEnum);
            request.setOrderId(orderId);
            request.setOrderAmount(payMoney.doubleValue());
            request.setOrderName("充值");
            request.setAttach("这里是附加的信息");

            log.info("【发起支付】request={}", JsonUtil.toJson(request));
            log.info("是否微信支付:orderForm.getPayType:{},BestPayTypeEnum.WXPAY_APP.getCode:{},是否：{}", orderForm.getPayType(), BestPayTypeEnum.WXPAY_APP.getCode(), orderForm.getPayType().equalsIgnoreCase(BestPayTypeEnum.WXPAY_APP.getCode()));
            log.info("bestPayTypeEnum == BestPayTypeEnum.WXPAY_APP：{}", bestPayTypeEnum == BestPayTypeEnum.WXPAY_APP);

            if (orderForm.getPayType().equalsIgnoreCase(BestPayTypeEnum.ALIPAY_APP.getCode())) {
                AlipayTradeAppPayResponse payResponse = aliAppPayService.pay(request);
                log.info("【支付宝支付结果】response={}", JsonUtil.toJson(payResponse));
                return Result.success(payResponse.getBody());
            } else if (bestPayTypeEnum == BestPayTypeEnum.WXPAY_APP) {
                log.info("开始调用微信支付:{}", BestPayTypeEnum.WXPAY_APP);
                Map map = weiXinPayService.wxPaybill(request);
                return Result.success(map);
            }

        }
        return result;
    }

    /**
     * 异步回调
     */
    @PostMapping(value = "/open/ali/notify")
    public void aliNotify(@RequestBody String notifyData) {
        log.info("【异步通知】支付平台的数据request={}", notifyData);
        PayResponse response = bestPayService.asyncNotify(notifyData);
        log.info("【异步通知】处理后的数据data={}", JsonUtil.toJson(response));
        String orderId = response.getOrderId();
        paySuccess(orderId);

    }

    private Result payByGold(User user, String orderId, String memberCardId) {
        Result<Wallet> walletResult = walletService.query(user.getId());
        Result<MemberCard> memberCardResult = memberCardService.memberCard(memberCardId);
        if (walletResult.isSuccess() && memberCardResult.isSuccess()) {
            Wallet wallet = walletResult.getData();
            MemberCard memberCard = memberCardResult.getData();
            int cost = memberCard.getPrice().multiply(new BigDecimal(10)).intValue();
            if (memberCard.getType().equals(MemberCardType.vip.getCode()) && wallet.getAmount() >=cost ) {
                WalletForm walletForm = new WalletForm();
                walletForm.setId(wallet.getId());
                int amount = wallet.getAmount() - cost;
                walletForm.setAmount(amount);
                log.info("更新钱包：{}", JsonUtil.toJson(walletForm));
                walletService.update(walletForm);
                ProfitRecordForm profitRecord = new ProfitRecordForm();
                profitRecord.setAmount(cost);
                profitRecord.setStatus(ProfitRecordStatus.pay.getCode());
                profitRecord.setType(ProfitRecordType.outcome.getCode());
                profitRecord.setUserId(user.getId());
                profitRecordService.save(profitRecord);
                log.info("保存交易记录={}", JsonUtil.toJson(profitRecord));
                paySuccess(orderId);
                return Result.success();
            } else {
                return Result.fail(UserErrorType.USER_WALLET_INSUFFICIENT);
            }
        }
        return Result.fail(UserErrorType.USER_WALLET_INSUFFICIENT);
    }

    private void paySuccess(String orderId) {

        Result<Order> orderResult = orderService.order(orderId);
        if (orderResult.isSuccess()) {
            Order order = orderResult.getData();
            if(order.getStatus().equalsIgnoreCase(OrderStatus.paid.getCode())){
                log.info("订单：{},已支付，不再重复处理",orderId);
                return;
            }
            OrderForm orderForm = new OrderForm();
            orderForm.setId(orderId);
            orderForm.setStatus(OrderStatus.paid.getCode());
            orderService.update(orderForm);


            Result<User> userResult = userService.getById(order.getUserId());
            Result<MemberCard> memberCardResult = memberCardService.memberCard(order.getMemberCardId());

            if (userResult.isSuccess() && memberCardResult.isSuccess()) {
                User user = userResult.getData();
                MemberCard memberCard = memberCardResult.getData();

                if (memberCard.getType().equals(MemberCardType.gold.getCode())) {
                    Result<Wallet> walletResult = walletService.query(user.getId());
                    if (walletResult.isSuccess()) {
                        Wallet wallet = walletResult.getData();
                        WalletForm walletForm = new WalletForm();
                        if (wallet != null) {
                            walletForm.setId(wallet.getId());
                            walletForm.setAmount(wallet.getAmount() + memberCard.getGoldNumber() + memberCard.getGiftNumber());
                            walletService.update(walletForm);
                            log.info("更新钱包余额");
                        } else {
                            walletForm.setUserId(user.getId());
                            walletForm.setAmount(memberCard.getGoldNumber() + memberCard.getGiftNumber());
                            walletService.add(walletForm);
                            log.info("创建钱包，并设置余额");
                        }
                        ProfitRecordForm profitRecord = new ProfitRecordForm();
                        profitRecord.setAmount(memberCard.getGoldNumber() + memberCard.getGiftNumber());
                        profitRecord.setStatus(ProfitRecordStatus.pay.getCode());
                        profitRecord.setType(ProfitRecordType.income.getCode());
                        profitRecord.setUserId(user.getId());
                        log.info("创建交易记录");
                        profitRecordService.save(profitRecord);
                    }
                } else if (memberCard.getType().equals(MemberCardType.vip.getCode())) {
                    log.info("购买会员卡");
                    if (user.getVipStatus().equals(VipStatus.no.getCode())) {
                        user.setVipStatus(VipStatus.yes.getCode());
                        user.setDeadline(DateUtils.addDays(new Date(), memberCard.getDayCount()));
                    } else if (user.getVipStatus().equals(VipStatus.yes.getCode())) {
                        if (user.getDeadline().before(new Date())) {
                            user.setDeadline(DateUtils.addDays(new Date(), memberCard.getDayCount()));
                        } else {
                            user.setDeadline(DateUtils.addDays(user.getDeadline(), memberCard.getDayCount()));
                        }
                    } else if (user.getVipStatus().equals(VipStatus.expired.getCode())) {
                        if (user.getDeadline().after(new Date())) {
                            user.setDeadline(DateUtils.addDays(new Date(), memberCard.getDayCount()));
                        }
                    }
                }
                userService.update(user);
            }
        }
    }

    @RequestMapping(value = "/order", method = RequestMethod.PUT)
    public Result update(HttpServletRequest request, @RequestBody OrderForm order) {
        User user = getUser(request);
        return orderService.update(order);
    }

    @RequestMapping(value = "/order/{id}", method = RequestMethod.GET)
    public Result get(@PathVariable String id) {
        return orderService.order(id);
    }

    @RequestMapping(value = "/order/{id}", method = RequestMethod.DELETE)
    public Result delete(@PathVariable String id) {
        orderService.delete(id);
        return Result.success();
    }

    @RequestMapping(value = "/order", method = RequestMethod.GET)
    public Result getDefaultOrder(HttpServletRequest request, String status) {
        User user = getUser(request);
        if (user == null) {
            return Result.fail(SystemErrorType.SYSTEM_BUSY);
        }
        OrderQueryParam param = new OrderQueryParam();
        param.setUserId(user.getId());
        if (StringUtils.isNotEmpty(status)) {
            param.setStatus(status);
        }
        return orderService.conditions(param);
    }
}
